package com.liuhuanss.voiceprint.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.liuhuanss.voiceprint.config.VoiceprintConfig;
import com.liuhuanss.voiceprint.config.VoiceprintProperties;
import com.liuhuanss.voiceprint.dto.LoginRequest;
import com.liuhuanss.voiceprint.dto.RegisterRequest;
import com.liuhuanss.voiceprint.entity.User;
import com.liuhuanss.voiceprint.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;

/**
 * 用户服务类
 * 
 * @author liuhuanss
 * @version 1.0
 */
@Slf4j
@Service
@Transactional
public class UserService {
    
    // 注入声纹识别配置
    
    @Autowired
    private VoiceprintProperties voiceprintProperties;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private VoiceprintService voiceprintService;

    @Autowired
    private VoiceprintConfig voiceprintConfig;

    @Autowired
    private PasswordEncoder passwordEncoder;

    /**
     * 用户注册
     * 
     * @param registerRequest 注册请求
     * @return 注册结果
     */
    public User registerUser(RegisterRequest registerRequest) {
        log.info("开始用户注册，用户名: {}, 邮箱: {}", registerRequest.getUsername(), registerRequest.getEmail());
        
        // 检查用户名是否已存在
        if (userMapper.existsByUsername(registerRequest.getUsername())) {
            throw new RuntimeException("用户名已存在");
        }
        
        // 检查邮箱是否已存在
        if (userMapper.existsByEmail(registerRequest.getEmail())) {
            throw new RuntimeException("邮箱已存在");
        }
        
        // 创建用户
        User user = new User();
        user.setUsername(registerRequest.getUsername());
        user.setEmail(registerRequest.getEmail());
        user.setPassword(passwordEncoder.encode(registerRequest.getPassword()));
        user.setIsActive(1);
        
        // 如果启用声纹识别
        if (registerRequest.getEnableVoiceprint() && StringUtils.hasText(registerRequest.getAudioBase64())) {
            try {
                // 创建声纹特征库（如果不存在）
                String groupId = voiceprintConfig.getDefaultGroupId();
                try {
                    Map<String, Object> result = voiceprintService.createGroup(groupId);
                    log.info("声纹特征库创建结果: {}", result);
                } catch (Exception e) {
                    log.warn("声纹特征库可能已存在: {}", e.getMessage());
                }
                
                // 生成唯一的特征ID
                String featureId = "feature_" + user.getUsername() + "_" + UUID.randomUUID().toString().substring(0, 8);
                
                // 添加声纹特征
                String result = voiceprintService.createFeature(registerRequest.getAudioBase64(), featureId, groupId);
                JSONObject resultJson = JSON.parseObject(result);
                
                if (resultJson.getInteger("ret") == 0) {
                    user.setVoiceprintFeatureId(featureId);
                    user.setVoiceprintGroupId(groupId);
                    user.setIsVoiceprintEnabled(1);
                    log.info("用户声纹特征创建成功，featureId: {}", featureId);
                } else {
                    log.error("声纹特征创建失败: {}", result);
                    throw new RuntimeException("声纹特征创建失败: " + resultJson.getString("msg"));
                }
            } catch (Exception e) {
                log.error("注册时创建声纹特征失败", e);
                throw new RuntimeException("声纹特征创建失败: " + e.getMessage());
            }
        } else {
            user.setIsVoiceprintEnabled(0);
        }
        
        userMapper.insert(user);
        log.info("用户注册成功，用户ID: {}", user.getId());
        return user;
    }

    /**
     * 用户登录
     * 
     * @param loginRequest 登录请求
     * @return 登录结果
     */
    public User loginUser(LoginRequest loginRequest) {
        log.info("开始用户登录，用户名: {}, 登录类型: {}", loginRequest.getUsername(), loginRequest.getLoginType());
        
        // 查找用户
        User user = userMapper.findByUsername(loginRequest.getUsername());
        if (user == null) {
            user = userMapper.findByEmail(loginRequest.getUsername());
        }
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        // 根据登录类型进行验证
        if ("voiceprint".equals(loginRequest.getLoginType())) {
            return loginWithVoiceprint(user, loginRequest.getAudioBase64());
        } else {
            return loginWithPassword(user, loginRequest.getPassword());
        }
    }

    /**
     * 密码登录
     */
    private User loginWithPassword(User user, String password) {
        if (!StringUtils.hasText(password)) {
            throw new RuntimeException("密码不能为空");
        }
        
        if (!passwordEncoder.matches(password, user.getPassword())) {
            throw new RuntimeException("密码错误");
        }
        
        log.info("用户密码登录成功，用户ID: {}", user.getId());
        return user;
    }

    /**
     * 声纹登录
     */
    private User loginWithVoiceprint(User user, String audioBase64) {
        if (!StringUtils.hasText(audioBase64)) {
            throw new RuntimeException("声纹音频不能为空");
        }
        
        if (!StringUtils.hasText(user.getVoiceprintFeatureId())) {
            throw new RuntimeException("用户声纹特征不存在");
        }
        
        try {
            // 进行1:1声纹比对
            Map<String, Object> result = voiceprintService.searchOneFeature(
                user.getVoiceprintGroupId(),
                user.getVoiceprintFeatureId(), 
                audioBase64
            );
            
            String resultStr = JSON.toJSONString(result);
            
            JSONObject resultJson = JSON.parseObject(resultStr);
            if (resultJson.getInteger("ret") != 0) {
                throw new RuntimeException("声纹识别失败: " + resultJson.getString("msg"));
            }
            
            // 获取相似度分数
            double score = resultJson.getDouble("score");
            double threshold = voiceprintProperties.getRecognition().getVoiceprintThreshold();
            log.info("声纹识别分数: {}, 阈值: {}", score, threshold);
            
            if (score >= threshold) {
                log.info("用户声纹登录成功，用户ID: {}, 分数: {}", user.getId(), score);
                return user;
            } else {
                throw new RuntimeException("声纹识别失败，相似度过低: " + score);
            }
        } catch (Exception e) {
            log.error("声纹登录失败", e);
            throw new RuntimeException("声纹登录失败: " + e.getMessage());
        }
    }

    /**
     * 启用声纹识别
     * 
     * @param userId 用户ID
     * @param audioBase64 音频Base64编码
     * @return 操作结果
     */
    public User enableVoiceprint(Long userId, String audioBase64) {
        log.info("开始为用户启用声纹识别，用户ID: {}", userId);
        
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        if (!StringUtils.hasText(audioBase64)) {
            throw new RuntimeException("声纹音频不能为空");
        }
        
        try {
            // 创建声纹特征库（如果不存在）
            String groupId = voiceprintConfig.getDefaultGroupId();
            try {
                voiceprintService.createGroup(groupId);
            } catch (Exception e) {
                log.warn("声纹特征库可能已存在: {}", e.getMessage());
            }
            
            // 生成唯一的特征ID
            String featureId = "feature_" + user.getUsername() + "_" + UUID.randomUUID().toString().substring(0, 8);
            
            // 添加声纹特征
            String result = voiceprintService.createFeature(audioBase64, featureId, groupId);
            JSONObject resultJson = JSON.parseObject(result);
            
            if (resultJson.getInteger("ret") == 0) {
                user.setVoiceprintFeatureId(featureId);
                user.setVoiceprintGroupId(groupId);
                user.setIsVoiceprintEnabled(1);
                
                userMapper.updateById(user);
                log.info("用户声纹识别启用成功，用户ID: {}, featureId: {}", userId, featureId);
                return user;
            } else {
                throw new RuntimeException("声纹特征创建失败: " + resultJson.getString("msg"));
            }
        } catch (Exception e) {
            log.error("启用声纹识别失败", e);
            throw new RuntimeException("启用声纹识别失败: " + e.getMessage());
        }
    }

    /**
     * 禁用声纹识别
     * 
     * @param userId 用户ID
     * @return 操作结果
     */
    public User disableVoiceprint(Long userId) {
        log.info("开始为用户禁用声纹识别，用户ID: {}", userId);
        
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        try {
            // 删除声纹特征
            if (StringUtils.hasText(user.getVoiceprintFeatureId())) {
                voiceprintService.deleteFeature(user.getVoiceprintFeatureId(), user.getVoiceprintGroupId());
            }
            
            user.setVoiceprintFeatureId(null);
            user.setVoiceprintGroupId(null);
            user.setIsVoiceprintEnabled(0);
            
            userMapper.updateById(user);
            log.info("用户声纹识别禁用成功，用户ID: {}", userId);
            return user;
        } catch (Exception e) {
            log.error("禁用声纹识别失败", e);
            throw new RuntimeException("禁用声纹识别失败: " + e.getMessage());
        }
    }

    /**
     * 根据用户名查找用户
     */
    public User findByUsername(String username) {
        return userMapper.findByUsername(username);
    }

    /**
     * 根据邮箱查找用户
     */
    public User findByEmail(String email) {
        return userMapper.findByEmail(email);
    }

    /**
     * 获取所有启用声纹识别的用户
     */
    public List<User> getAllVoiceprintEnabledUsers() {
        return userMapper.selectList(
            new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<User>()
                .eq("is_voiceprint_enabled", true)
                .eq("is_active", true)
                .eq("deleted", 0)
        );
    }

    /**
     * 根据ID查找用户
     */
    public User findById(Long id) {
        return userMapper.selectById(id);
    }

    /**
     * 获取启用声纹识别的用户数量
     */
    public long countVoiceprintEnabledUsers() {
        return userMapper.selectCount(
            new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<User>()
                .eq("is_voiceprint_enabled", true)
                .eq("is_active", true)
                .eq("deleted", 0)
        );
    }
    
    /**
     * 保存用户
     * 
     * @param user 用户对象
     * @return 保存后的用户对象
     */
    public User save(User user) {
        if (user.getId() == null) {
            userMapper.insert(user);
        } else {
            userMapper.updateById(user);
        }
        return user;
    }
}